//
//  ARPostEditController.swift
//  AquaRaft
//
//  Created by 何启亮 on 2024/4/10.
//

import UIKit
import JKSwiftExtension
import SnapKit
import AttributedString
import Photos

/// 发布作品 - 编辑的控制器
/// - note:
///  标题 + 内容 + 选择图片
class ARPostEditController: ARBaseViewController, UIGestureRecognizerDelegate {

    var isIndexPostStyle = true {
        didSet {
            self.configUIByStyle(isIndexPostStyle)
        }
    }
    
    var contentDidChangeCallback: (() -> Void)?
    
    // MARK: - Private property
    
    private static let cellRowCount = 3
    private static let cellSpacing = 14.0
    private static let viewPadding = 20.0
    
    // 宽度计算
    private static let cellWidth: CGFloat = {
        let totalCellSpacing = CGFloat(cellRowCount - 1) * cellSpacing
        let totalViewPadding = viewPadding * 2
        let width = (ARHelper.screenWidth() - totalCellSpacing - totalViewPadding) / CGFloat(cellRowCount)
        return floor(width)
    }()
    // cell高度固定
    private static let cellHeight = 118.0
    private static let cellReuseId = "AR.postImgCellReuseId"
    
    private let viewModel = ARPostEditViewModel()
    
    // MARK: - LifeCycle
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.setupUI()
    }
    
    // MARK: - UI
    
    private func setupUI() {
        self.view.addSubview(textField)
        self.view.addSubview(separatorLine)
        self.view.addSubview(textContentView)
        self.view.addSubview(collectionView)
        
        textField.snp.makeConstraints { make in
            make.left.equalToSuperview().offset(20)
            make.right.equalToSuperview().offset(-20)
            make.height.equalTo(24)
            make.top.equalToSuperview().offset(20)
        }
        
        separatorLine.snp.makeConstraints { make in
            make.left.right.equalTo(textField)
            make.top.equalTo(textField.snp.bottom).offset(20)
            make.height.equalTo(1)
        }
        
        textContentView.snp.makeConstraints { make in
            make.top.equalTo(separatorLine.snp.bottom).offset(20)
            make.left.right.equalTo(textField)
            make.height.equalTo(202)
        }
        
        collectionView.snp.makeConstraints { make in
            make.left.right.equalTo(textField)
            make.top.equalTo(textContentView.snp.bottom).offset(24)
            make.height.equalTo(Self.cellHeight)
            make.bottom.equalToSuperview()
        }
        
        // 更新一下
        self.updateCollectionViewHeight()
        self.textViewDidChange(self.textView)
        
        configUIByStyle(isIndexPostStyle)
        
        // tap action
        let tap = UITapGestureRecognizer(target: self, action: #selector(tapAction(_:)))
        tap.delegate = self
        self.view.addGestureRecognizer(tap)
    }
    
    @objc private func tapAction(_ gesture: UITapGestureRecognizer) {
        self.view.endEditing(true)
    }
    
    // MARK: UI Helper
    
    private func updateCollectionViewHeight() {
        // 计算行数
        let count = viewModel.numberOfItem()
        let row = count / Self.cellRowCount + (count % Self.cellRowCount > 0 ? 1 : 0)
        let height = CGFloat(row) * Self.cellHeight + Self.cellSpacing * CGFloat(row - 1)
        collectionView.snp.updateConstraints { make in
            make.height.equalTo(height)
        }
    }
    
    private func configUIByStyle(_ isIndexPostStyle: Bool) {
        if isIndexPostStyle {
            let textFieldPlaceholder = ASAttributedString.init(string: ARHelper.localString("Enter the rafting location name."),
                .font(ARHelper.font(20, weight: .regular)),
                .foreground(UIColor(hexString: "#565656") ?? .black)
            ).value
            textField.attributedPlaceholder = textFieldPlaceholder
            textField.textColor = .black
            return
        }
        
        let textFieldPlaceholder = ASAttributedString.init(string: ARHelper.localString("Enter your title ："),
            .font(ARHelper.font(20, weight: .regular)),
            .foreground(.black.withAlphaComponent(0.5))
        ).value
        textField.attributedPlaceholder = textFieldPlaceholder
        textField.textColor = .black
        
        textView.placeHolder = ARHelper.localString("Start creating your ideas.....")
        textView.font = ARHelper.font(12, weight: .regular)
        textView.placeHolderColor = .black.withAlphaComponent(0.5)
        textView.textColor = .black
    }
    
    // MARK: - Action
    
    func judgeWorkCanPost() -> Bool {
        return viewModel.judgeWorkCanPost()
    }
    func createWork() -> ARWorkModel? {
        return viewModel.createWork()
    }
    
    // MARK: - UIGestureRecognizerDelegate
    
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        let location = gestureRecognizer.location(in: self.collectionView)
        if self.collectionView.point(inside: location, with: nil) {
            return false
        }
        return true
    }

    // MARK: - Lazy
    
    private lazy var textField: UITextField = {
        let textfiled = UITextField()
        textfiled.font = ARHelper.font(20, weight: .regular)
        textfiled.delegate = self
        return textfiled
    }()
    
    private lazy var separatorLine: UIView = {
        let view = UIView()
        view.backgroundColor = UIColor(hexString: "#CCCCCC")
        return view
    }()
    
    private lazy var textView: JKPlaceHolderTextView = {
        let textView = JKPlaceHolderTextView()
        textView.delegate = self
        textView.font = ARHelper.font(12, weight: .regular)
        textView.backgroundColor = .clear
        return textView
    }()
    
    private lazy var countLabel: UILabel = {
        let label = UILabel()
        label.font = ARHelper.font(12, weight: .regular)
        label.textColor = .black.withAlphaComponent(0.5)
        label.textAlignment = .right
        return label
    }()
    
    private lazy var textContentView: UIView = {
        let view = UIView()
        view.backgroundColor = UIColor(hexString: "#F2F2F2")
        view.layer.cornerRadius = 8
        
        view.addSubview(textView)
        view.addSubview(countLabel)
        
        textView.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(12)
            make.left.equalToSuperview().offset(10)
            make.right.equalToSuperview().offset(-10)
            make.bottom.equalTo(countLabel.snp.top).offset(-10)
        }
        
        countLabel.snp.makeConstraints { make in
            make.left.equalToSuperview()
            make.right.equalToSuperview().offset(-16)
            make.height.equalTo(12)
            make.bottom.equalToSuperview().offset(-16)
        }
        
        return view
    }()
    
    private lazy var collectionView: UICollectionView = {
        
        let flow = UICollectionViewFlowLayout()
        flow.itemSize = .init(width: Self.cellWidth, height: Self.cellHeight)
        flow.scrollDirection = .vertical
        flow.minimumLineSpacing = Self.cellSpacing
        flow.minimumInteritemSpacing = Self.cellSpacing
        
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: flow)
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.register(ARPostImageCell.self, forCellWithReuseIdentifier: Self.cellReuseId)
        
        collectionView.isPagingEnabled = true
        collectionView.backgroundColor = .clear
        return collectionView
    }()
}

extension ARPostEditController: UITextFieldDelegate {
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        
        let currentText = textField.text ?? ""
        guard let stringRange = Range(range, in: currentText) else { return false }
        
        // 更新后的文本
        let updatedText = currentText.replacingCharacters(in: stringRange, with: string)
        
        // 如果更新后的文本的字符数不超过100，就返回 true；否则，返回 false
        return updatedText.count <= 100
    }
    
    func textFieldDidChangeSelection(_ textField: UITextField) {
        self.viewModel.titleStr = textField.text
        // 通知修改
        contentDidChangeCallback?()
    }
}

extension ARPostEditController: UITextViewDelegate {
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        let currentText = textView.text ?? ""
        guard let stringRange = Range(range, in: currentText) else { return false }

        // 更新后的文本
        let updatedText = currentText.replacingCharacters(in: stringRange, with: text)

        // 如果更新后的文本的字符数不超过100，就返回 true；否则，返回 false
        return updatedText.count <= 600
    }
    
    func textViewDidChange(_ textView: UITextView) {
        
        self.viewModel.contentStr = textView.text
        
        // 字数
        self.countLabel.text = "\(textView.text?.count ?? 0)/600"
        
        // 通知修改
        contentDidChangeCallback?()
    }
}

extension ARPostEditController: UICollectionViewDelegate, UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let path = viewModel.pathOf(item: indexPath.row)
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Self.cellReuseId, for: indexPath) as! ARPostImageCell
        cell.updateCell(imagePath: path, deleteStyleIsIndex: self.isIndexPostStyle)
        cell.deleteCallback = { [weak self] in
            if let path = path {
                self?.viewModel.deleteImageOf(path)
                self?.collectionView.reloadData()
            }
        }
        return cell
    }
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return viewModel.numberOfItem()
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if viewModel.isTakePhotoOf(item: indexPath.row) {
            self.selectPhoto()
        }
    }
    
}

/// Select photo
extension ARPostEditController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    
    fileprivate func selectPhoto() {
        let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
        let photoLibraryAction = UIAlertAction(title: "Choose from Photo Library", style: .default) { [weak self] _ in
            self?._selectPhotoFromLibrary()
        }
        let cameraAction = UIAlertAction(title: "Take Photo", style: .default) { [weak self] _ in
            self?._takePhoto()
        }
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
        alertController.addAction(cameraAction)
        alertController.addAction(photoLibraryAction)
        alertController.addAction(cancelAction)
        self.present(alertController, animated: true, completion: nil)
    }
    
    private func _takePhoto() {
        
        func takePhoto() {
            DispatchQueue.main.async {
                let imagePicker = UIImagePickerController()
                imagePicker.delegate = self
                imagePicker.sourceType = .camera
                imagePicker.cameraCaptureMode = .photo
                self.present(imagePicker, animated: true)
            }
        }
        
        let authStatus = AVCaptureDevice.authorizationStatus(for: .video)
        switch authStatus {
        case .notDetermined:
            AVCaptureDevice.requestAccess(for: .video) { [weak self] author in
                if author {
                    takePhoto()
                    return
                }
                self?.ar.makeToast(ARHelper.localString("No permission"))
            }
        case .restricted, .denied:
            self.ar.makeToast(ARHelper.localString("No permission"))
        case .authorized:
            takePhoto()
        @unknown default:
            self.ar.makeToast(ARHelper.localString("No permission"))
        }
    }
    
    private func _selectPhotoFromLibrary() {
        // 权限
        getPHPhotoLibraryAuthorized { [weak self] isHaveAuthorizes, authorizeStatus in
            if isHaveAuthorizes == false {
                self?.ar.makeToast(ARHelper.localString("No permission"))
                return
            }
            
            DispatchQueue.main.async {
                self?._selectPhoto()
            }
        }
    }
    
    private func _selectPhoto() {
        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.sourceType = .photoLibrary
        present(imagePicker, animated: true)
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let selectedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            // 在这里，你可以使用 selectedImage
            
            // 保存到本地
            let path = ARFileHelper.createImagePath()
            if let data = selectedImage.jpegData(compressionQuality: 0.8) {
                do {
                    try data.write(to: NSURL(fileURLWithPath: path) as URL)
                    
                    // 回调给viewmodel
                    self.viewModel.addImage(path)
                    DispatchQueue.main.async {
                        self.collectionView.reloadData()
                        self.updateCollectionViewHeight()
                        
                        self.contentDidChangeCallback?()
                    }
                } catch {
                    self.ar.makeToast(ARHelper.localString("Failed to select image"))
                }
            } else {
                // 失败
                self.ar.makeToast(ARHelper.localString("Failed to select image"))
            }
        }
        dismiss(animated: true, completion: nil)
    }
    
    // MARK: Helper
    
    private func getPHPhotoLibraryAuthorized(resultClosure: @escaping ((_ isHaveAuthorizes: Bool, _ authorizeStatus: PHAuthorizationStatus) -> Void)) {
        let authorized = PHPhotoLibrary.authorizationStatus()
        if authorized == .notDetermined {
            PHPhotoLibrary.requestAuthorization { status in
                if status == .authorized {
                    resultClosure(true, status)
                } else {
                    resultClosure(false, status)
                }
            }
        } else if authorized == .denied || authorized == .restricted {
            resultClosure(false, authorized)
        } else {
            // authorized
            resultClosure(true, authorized)
        }
    }
}
